﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.DataLayer.EsgRatings;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.ESG.Entities;
using Sustainalytics.ESGRatings.BusinessLogic.ESGOnlineReport;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Sustainalytics.ESGRatings.Service.Tests
{
    [TestClass]
    public class OnlineResearchProductsBusinessLogicUnitTests
    {
        [TestMethod]
        public void GetIndicatorsByCompanyThemeAndCluster_SearchIndicator()
        {
            var themeId = Guid.NewGuid();
            const string themeName = "Governance";
            const string clusterName = "Preparedness";
            const int pageSize = 5;
            const int totalIndicators = 8;
            var searchedIndicator = "G.1." + (pageSize + 2);

            var indicatorTemplates = new List<IndicatorTemplate>
            {
                new IndicatorTemplate { ThemeId = themeId, ThemeName = themeName, IndicatorCategory = clusterName }
            };
            var rpIndicatorsExtended = Enumerable.Range(1, totalIndicators).Select(i => new RPIndicatorExtended
            {
                Number = "G.1." + i, 
                Template = new IndicatorTemplate { Number = "G.1." + i, ThemeId = themeId, ThemeName = themeName, IndicatorCategory = clusterName }, 
                SelectedAnswer = new AnswerCategory(), 
                UniverseIds = new List<int> {1}
            }).ToList();

            var templatesRepository = new Moq.Mock<IRepositoryCollection<IndicatorTemplate>>();
            templatesRepository.Setup(m => m.ReadAllWhere(
                It.IsAny<Expression<Func<IndicatorTemplate, bool>>>(),
                It.IsAny<int?>(),
                It.IsAny<int?>(),
                It.IsAny<Ordering<IndicatorTemplate>>(), 
                It.IsAny<bool>(), 
                It.IsAny<string[]>()))
                .Returns((Expression<Func<IndicatorTemplate, bool>> predicate, int? skip, int? take, Ordering<IndicatorTemplate> ordering) => indicatorTemplates.Where(predicate.Compile()).ToList());

            var standardIndicatorsRepository = new Moq.Mock<IStandardIndicatorsRepository>();
            standardIndicatorsRepository.Setup(m => m.ReadAllWhere(
                It.IsAny<Guid>(),
                It.IsAny<Guid>(),
                It.IsAny<string>(),
                It.IsAny<int?>(),
                It.IsAny<int?>(),
                It.IsAny<Ordering<RPIndicatorExtended>>(), 
                It.IsAny<Expression<Func<RPIndicatorExtended, object>>[]>()
               ))
                .Returns((Guid companyId, Guid tId, string cluster, int? skip, int? take, Ordering<RPControversyIndicator> ordering, Expression<Func<RPControversyIndicator, object>>[] includeFields) => rpIndicatorsExtended.Skip(skip ?? 0).Take(take ?? rpIndicatorsExtended.Count).ToList()
            );

            var controversyIndicatorsRepository = new Mock< IControversyIndicatorsRepository>();
            var themePerformanceRepository = new Mock<IRepositoryCollection<RPCompanyESGComputationResult>>();

            var onlineRpBlUnit = new OnlineResearchProductsBusinessLogicUnit(templatesRepository.Object, standardIndicatorsRepository.Object, controversyIndicatorsRepository.Object,themePerformanceRepository.Object);

            var retrievedIndicators = onlineRpBlUnit.GetIndicatorsByCompanyThemeAndCluster(Guid.NewGuid(),Guid.NewGuid(), themeName, clusterName, new List<int> {1}, searchedIndicator, 0, pageSize).ToList();

            Assert.IsTrue(retrievedIndicators.FindIndex(i => i.Code == searchedIndicator) > pageSize, string.Format("Searched indicator {0} not found on the second page as expected", searchedIndicator));
        }
    }
}
